/* eslint-disable max-len */
import { Ref, ref } from "vue";
import { DesignerHTMLElement, DraggingResolveContext, UseDesignerRules } from "../types";
import { ComponentSchema, DesignerComponentInstance, DesignerItemContext } from "../../types";
import { getSchemaByType } from '../../../../dynamic-resolver/src/schema-resolver';

export function useDesignerComponent(
    elementRef: Ref<HTMLElement>,
    designItemContext: DesignerItemContext,
    designerRules?: UseDesignerRules
): Ref<DesignerComponentInstance> {
    designerRules?.resolveComponentContext && designerRules.resolveComponentContext();
    const styles = (designerRules && designerRules.getStyles && designerRules.getStyles()) || '';
    const componentInstance = ref<DesignerComponentInstance>();
    /**
     * 校验组件是否支持移动
     */
    function checkCanMoveComponent(): boolean {
        if (designItemContext.schema.componentType === 'frame') {
            return false;
        }
        if (designerRules && designerRules.checkCanMoveComponent) {
            return designerRules.checkCanMoveComponent();
        }
        return true;
    }

    /**
     * 校验组件是否支持选中父级
     */
    function checkCanSelectParentComponent(): boolean {
        return false;
    }

    /**
     * 校验组件是否支持删除
     */
    function checkCanDeleteComponent() {
        if (designItemContext.schema.componentType === 'frame') {
            return false;
        }
        if (designerRules && designerRules.checkCanDeleteComponent) {
            return designerRules.checkCanDeleteComponent();
        }
        return true;
    }

    /**
     * 判断在可视化区域中是否隐藏容器间距和线条
     */
    function hideNestedPaddingInDesginerView() {
        if (designItemContext.schema.componentType === 'frame') {
            return true;
        }
        if (designerRules && designerRules.hideNestedPaddingInDesginerView) {
            return designerRules.hideNestedPaddingInDesginerView();
        }
        return false;
    }

    /**
     * 获取组件在表单DOM中所属的Component的实例
     * @param componentInstance 组件实例
     */
    function getBelongedComponentInstance(componentInstance?: Ref<DesignerComponentInstance>): DesignerComponentInstance | null {
        if (!componentInstance || !componentInstance.value) {
            return null;
        }
        if (componentInstance.value.schema && componentInstance.value.schema.type === 'component') {
            return componentInstance.value;
        }
        const parent = ref(componentInstance?.value.parent) as Ref<DesignerComponentInstance>;
        const grandParent = getBelongedComponentInstance(parent);
        if (grandParent) {
            return grandParent;
        }
        return null;
    }

    function getDraggableDesignItemElement(context: DesignerItemContext = designItemContext): Ref<any> | null {
        const { componentInstance, designerItemElementRef } = context;
        if (!componentInstance || !componentInstance.value) {
            return null;
        }
        if (componentInstance.value.canMove) {
            return designerItemElementRef;
        }
        return getDraggableDesignItemElement(context.parent);
    }

    /**
     * 判断是否可以接收拖拽新增的子级控件
     * @param data 新控件的类型、所属分类
     * @returns boolean
     */
    function canAccepts(draggingContext: DraggingResolveContext) {
        return !!designerRules && designerRules.canAccepts(draggingContext);
    }

    function getDraggingDisplayText() {
        return designItemContext?.schema.label || designItemContext?.schema.title || designItemContext?.schema.name;
    }

    /**
     * 控件可以拖拽到的最外层容器，用于限制控件向外层容器拖拽的范围。不写则不限制
     */
    function getDragScopeElement(): HTMLElement | undefined {
        return undefined;
    }

    /**
     * 移动控件后事件：在可视化设计器中，将现有的控件移动到容器中
     * @param element 移动的源DOM结构
     */
    function onAcceptMovedChildElement(element: DesignerHTMLElement, soureeElement?: DesignerHTMLElement) {
        if (!soureeElement) {
            return;
        }
        if (designerRules?.onAcceptMovedChildElement) {
            designerRules.onAcceptMovedChildElement(soureeElement);
        }
    }

    /**
     * 当前容器接收新创建的子控件
     */
    function onAcceptNewChildElement(element: DesignerHTMLElement, targetPosition: number): ComponentSchema {
        const componentType = String(element.getAttribute('data-controltype'));
        const featureString = element.getAttribute('data-feature');
        const resolveContext = featureString ? JSON.parse(featureString) : {};
        resolveContext.parentComponentInstance = componentInstance.value;
        let componentSchema = getSchemaByType(componentType, resolveContext) as ComponentSchema;
        if (designerRules && designerRules.onAcceptNewChildElement) {
            componentSchema = designerRules.onAcceptNewChildElement(element, targetPosition, componentSchema);
        }

        const typePrefix = componentType.toLowerCase().replace('-', '_');
        if (componentSchema && !componentSchema.id && componentSchema.type === componentType) {
            componentSchema.id = `${typePrefix}_${Math.random().toString().slice(2, 6)}`;
        }
        return componentSchema;
    }

    /**
     * 移动内部控件后事件：在可视化设计器中，将现有的控件移动到容器中
     * @param element 移动的源DOM结构
     */
    function onChildElementMovedOut(element: HTMLElement) {

    }

    /** 属性面板属性 */
    function getPropConfig(){
        if (designerRules && designerRules.getPropsConfig) {
            return designerRules.getPropsConfig();
        }
        console.log('1');
        return [];
    }

    componentInstance.value = {
        canMove: checkCanMoveComponent(),
        canSelectParent: checkCanSelectParentComponent(),
        canDelete: checkCanDeleteComponent(),
        canNested: !hideNestedPaddingInDesginerView(),
        contents: designItemContext.schema.contents,
        elementRef,
        parent: designItemContext.parent?.componentInstance,
        schema: designItemContext.schema,
        styles,
        canAccepts,
        getBelongedComponentInstance,
        getDraggableDesignItemElement,
        getDraggingDisplayText,
        getPropConfig,
        getDragScopeElement,
        onAcceptMovedChildElement,
        onAcceptNewChildElement,
        onChildElementMovedOut,
        triggerBelongedComponentToMoveWhenMoved: !!designerRules && designerRules.triggerBelongedComponentToMoveWhenMoved || ref(false),
        triggerBelongedComponentToDeleteWhenDeleted: !!designerRules && designerRules.triggerBelongedComponentToDeleteWhenDeleted || ref(false)
    } as DesignerComponentInstance;

    return componentInstance;

}
